﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;
using System.Linq;
using WebPart = System.Web.UI.WebControls.WebParts.WebPart;
using Microsoft.SharePoint.WebPartPages;
using System.Reflection;
using System.Collections;
using System.Web.UI.WebControls.WebParts;

namespace RGB.SharePoint.Util.Extensions
{
    public static class WebPartUtils
    {
        /// <summary>
        /// Finds webpart by type
        /// </summary>
        /// <param name="webParts"></param>
        /// <param name="webPartType"></param>
        /// <returns></returns>
        public static WebPart FindByType(this SPLimitedWebPartCollection webParts, Type webPartType)
        {            
            var part = webParts.OfType<WebPart>().SingleOrDefault(w => w.GetType().Equals(webPartType));
            return part;
        }

        /// <summary>
        /// Finds webpart by type
        /// </summary>
        /// <param name="webParts"></param>
        /// <param name="webPartType"></param>
        /// <param name="zoneId"></param>
        /// <param name="zoneIndex"></param>
        /// <returns></returns>
        public static WebPart FindByType(this SPLimitedWebPartCollection webParts, Type webPartType, string zoneId, int zoneIndex)
        {
            var part = webParts.OfType<WebPart>().SingleOrDefault(w => (w.GetType().Equals(webPartType) && w.Zone.ID.Equals(zoneId) && w.ZoneIndex == zoneIndex));
            return part;
        }

        /// <summary>
        /// Finds webpart by title
        /// </summary>
        /// <param name="webParts"></param>
        /// <param name="title"></param>
        /// <param name="zoneId"></param>
        /// <param name="zoneIndex"></param>
        /// <returns></returns>
        public static WebPart FindByTitle(this SPLimitedWebPartCollection webParts, string title, string zoneId, int zoneIndex)
        {
            var part = webParts.OfType<WebPart>().SingleOrDefault(w => (w.Title == title && w.Zone.ID.Equals(zoneId) && w.ZoneIndex == zoneIndex));
            return part;
        }

        /// <summary>
        /// Finds webpart by title
        /// </summary>
        /// <param name="webParts"></param>
        /// <param name="title"></param>
        /// <returns></returns>
        public static WebPart FindByTitle(this SPLimitedWebPartCollection webParts, string title)
        {
            var part = webParts.OfType<WebPart>().SingleOrDefault(w => w.Title == title);
            return part;
        }

        /// <summary>
        /// Check if WebPart is present in webpart collection
        /// </summary>
        /// <param name="webParts"></param>
        /// <param name="title"></param>
        /// <returns></returns>
        public static bool Contains(this SPLimitedWebPartCollection webParts, string title)
        {
            var part = webParts.FindByTitle(title);
            return part != null;
        }

        /// <summary>
        /// Adds web part to the page on website
        /// </summary>
        /// <param name="web"></param>
        /// <param name="pagePath"></param>
        /// <param name="webPartZoneId"></param>
        /// <param name="webPartSequence"></param>
        /// <param name="webPart"></param>
        public static void AddWebPart(this SPWeb web, string pagePath, string webPartZoneId, int webPartSequence, WebPart webPart)
        {
            SPFile webPartPage = web.GetFile(web.Url + pagePath);
            using (SPLimitedWebPartManager manager = webPartPage.GetLimitedWebPartManager(PersonalizationScope.Shared))
            {
                if (!manager.WebParts.Contains(webPart.Title))
                {
                    manager.AddWebPart(webPart, webPartZoneId, webPartSequence);
                }
            }
        }

        /// <summary>
        /// Removes web part from the page on website
        /// </summary>
        /// <param name="web"></param>
        /// <param name="pagePath"></param>
        /// <param name="webPartTitle"></param>
        public static void RemoveWebPart(this SPWeb web, string pagePath, string webPartTitle)
        {
            SPFile webPartPage = web.GetFile(web.Url + pagePath);
            using (SPLimitedWebPartManager manager = webPartPage.GetLimitedWebPartManager(PersonalizationScope.Shared))
            {
                WebPart webPart = manager.WebParts.FindByTitle(webPartTitle);

                if (webPart != null)
                {
                    manager.DeleteWebPart(webPart);
                }
            }
        }
    }
}
